package timing.ukulele.portal.controller;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RestController;
import timing.ukulele.common.data.ResponseData;
import timing.ukulele.data.portal.data.AntMenuConfigAccessTree;
import timing.ukulele.data.portal.view.AntMenuTreeVO;
import timing.ukulele.data.portal.view.AntMenuVO;
import timing.ukulele.facade.portal.mvc.AntMenuControllerFacade;
import timing.ukulele.portal.convertor.MenuConverter;
import timing.ukulele.portal.dictionary.MenuType;
import timing.ukulele.portal.persistent.AntMenu;
import timing.ukulele.portal.persistent.SysRole;
import timing.ukulele.portal.service.AntMenuService;
import timing.ukulele.portal.service.SysRoleService;
import timing.ukulele.share.UserLabelEnum;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static timing.ukulele.portal.util.MenuUtil.createMenuTreeVO;

@RestController
public final class AntMenuController implements AntMenuControllerFacade {
    private final AntMenuService antMenuService;
    private final SysRoleService roleService;

    @Autowired
    public AntMenuController(AntMenuService menuAntService, SysRoleService roleService) {
        this.antMenuService = menuAntService;
        this.roleService = roleService;
    }

    @Override
    public ResponseData<AntMenuVO> get(Long id) {
        if (id == null || id <= 0) {
            return ResponseData.paramError();
        }
        AntMenu menu = this.antMenuService.getById(id);
        if (menu == null) {
            return ResponseData.success();
        }
        AntMenuVO vo = MenuConverter.INSTANCE.p2v(menu);
        return ResponseData.success(vo);
    }

    @Override
    public ResponseData<List<AntMenuVO>> getByParam(Map<String, Object> map) {
        List<AntMenu> poList = this.antMenuService.listByMap(map);
        if (CollectionUtils.isEmpty(poList)) {
            return ResponseData.success();
        }
        List<AntMenuVO> voList = MenuConverter.INSTANCE.p2vList(poList);
        return ResponseData.success(voList);
    }

    @Override
    public ResponseData<List<AntMenuTreeVO>> getMenuTree(Boolean deleted) {
        LambdaQueryChainWrapper<AntMenu> query = this.antMenuService.lambdaQuery();
        if (deleted != null)
            query.eq(AntMenu::getDeleted, deleted);
        query.orderByAsc(AntMenu::getRank);
        List<AntMenu> list = query.list();
        return ResponseData.success(createMenuTreeVO(list));
    }

    @Override
    public ResponseData<List<AntMenuTreeVO>> getBusinessMenuTree(Boolean deleted) {
        LambdaQueryChainWrapper<AntMenu> query = this.antMenuService.lambdaQuery();
        if (deleted != null)
            query.eq(AntMenu::getDeleted, deleted);
        query.orderByAsc(AntMenu::getRank);
        List<AntMenu> list = query.list();
        if (CollectionUtils.isEmpty(list))
            return ResponseData.success(new ArrayList<>(0));
        // 超管的菜单要排除
        List<AntMenu> businessList = list.stream().filter(item -> !item.getAcl().contains(UserLabelEnum.OPERATOR.getLabel())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(businessList))
            return ResponseData.success(new ArrayList<>(0));
        return ResponseData.success(createMenuTreeVO(businessList));
    }

    @Override
    public ResponseData<Boolean> add(String currentUser, AntMenuVO sysMenuAnt) {
        if (sysMenuAnt == null || sysMenuAnt.getId() != null) {
            return ResponseData.paramError();
        }
        // 默认是网页端
        if (sysMenuAnt.getType() == null)
            sysMenuAnt.setType(MenuType.WEB.getCode());
        if (!MenuType.hasValue(sysMenuAnt.getType())) {
            return ResponseData.paramError("不支持的菜单类型");
        }
        if (sysMenuAnt.getParentId() != null && sysMenuAnt.getParentId() > 0) {
            AntMenu parent = this.antMenuService.lambdaQuery()
                    .eq(AntMenu::getId, sysMenuAnt.getParentId()).select(AntMenu::getType).one();
            if (parent == null)
                return ResponseData.error("父菜单不存在");
            if (!parent.getType().equals(sysMenuAnt.getType())) {
                return ResponseData.error("必须与父菜单的类型一致");
            }
        }
        AntMenu po = MenuConverter.INSTANCE.v2p(sysMenuAnt);
        if (!CollectionUtils.isEmpty(sysMenuAnt.getAcl())) {
            po.setAcl(JSON.toJSONString(sysMenuAnt.getAcl()));
        }
        po.setCreateBy(currentUser);
        po.setUpdateBy(currentUser);
        return ResponseData.success(this.antMenuService.save(po));
    }

    @Override
    public ResponseData<Boolean> edit(String currentUser, AntMenuVO sysMenuAnt) {
        if (sysMenuAnt == null || sysMenuAnt.getId() == null) {
            return ResponseData.paramError();
        }
        // TODO 修改四父子菜单的类型必须一致
        AntMenu po = MenuConverter.INSTANCE.v2p(sysMenuAnt);
        if (!CollectionUtils.isEmpty(sysMenuAnt.getAcl())) {
            po.setAcl(JSON.toJSONString(sysMenuAnt.getAcl()));
        }
        po.setUpdateBy(currentUser);
        return ResponseData.success(this.antMenuService.saveOrUpdate(po));
    }

    @Override
    public ResponseData<List<AntMenuConfigAccessTree>> getRoleMenuConfig(Long roleId, Boolean isSuper) {
        SysRole role = roleService.getById(roleId);
        if (role == null) {
            return ResponseData.paramError("不存在该角色");
        }
        List<AntMenuConfigAccessTree> config = this.antMenuService.getRoleMenuConfig(roleId, role.getType(), isSuper);
        return ResponseData.success(config);
    }

    @Override
    public ResponseData<Boolean> setRoleMenuConfig(Long roleId, List<AntMenuConfigAccessTree> list) {
        SysRole role = this.roleService.getById(roleId);
        if (role == null)
            return ResponseData.error("角色不存在");
        return new ResponseData<>(this.antMenuService.setRoleMenuConfig(role, list));
    }

}
